<html>
<head><meta charset="utf-8"><title>Enum memory layout, ffi, uninitialized values and UB · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html">Enum memory layout, ffi, uninitialized values and UB</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="192453317"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192453317" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192453317">(Mar 31 2020 at 21:39)</a>:</h4>
<p>I'm not sure if that's the right place to ask this kind of question, so if I should ask such questions somewhere else I would be  happy to hear where.</p>
<p>I'm currently reviewing a diesel <a href="https://github.com/diesel-rs/diesel/pull/2325" title="https://github.com/diesel-rs/diesel/pull/2325">PR</a> that implements support for custom aggregate functions for sqlite. At FFI boundary such functions are provided as set of function pointers. As an aggregate function needs to handle some state, therefore sqlite provides a function to receive the corresponding state for the current function call. <a href="https://www.sqlite.org/c3ref/aggregate_context.html" title="https://www.sqlite.org/c3ref/aggregate_context.html">This function</a> should be called in of the the callbacks/functions provided as implementation to sqlite. Now their documentation states</p>
<blockquote>
<p>The first time the sqlite3_aggregate_context(C,N) routine is called for a particular aggregate function, SQLite allocates N bytes of memory, zeroes out that memory, and returns a pointer to the new memory. On second and subsequent calls to sqlite3_aggregate_context() for the same aggregate function instance, the same buffer is returned. </p>
</blockquote>
<p>so it's basically a malloc kind function. To save some indirection here and because we do need to handle a certain wrap around all state either way one idea was to have those N bytes of memory directly represent basically an <code>Option</code> of our state. This leads me to the following questions regarding to what guarantees are made by rust(c) and what's undefined behaviour:</p>
<ol>
<li>I'm right to assume that the enum discriminates of <code>std::option::Option</code> are considered to be an implementation detail?  So I should not assume that <code>Option::None</code> has a zero discriminant?</li>
<li>Building on top of 1: For the following enum it's fine to say that the discriminate of <code>MyOption::None</code> is zero?</li>
</ol>
<div class="codehilite"><pre><span></span><span class="cp">#[repr(u8)]</span><span class="w"></span>
<span class="k">enum</span> <span class="nc">MyOption</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">// Discriminant is 0</span>
<span class="w">    </span><span class="cp">#[allow(dead_code)]</span><span class="w"></span>
<span class="w">    </span><span class="nb">None</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">A</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<ol start="3">
<li>As we don't have any information about the inner type of the <code>Some</code> variant: It's fine that this would point to potential uninitialized memory, because 2 would guarantee us that we have the <code>None</code> variant that does not hold any other information?</li>
</ol>



<a name="192462323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192462323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192462323">(Mar 31 2020 at 22:40)</a>:</h4>
<p><span class="user-mention" data-user-id="215423">@weiznich</span> The reasoning about the code in the second example is not correct. <code>MyOption</code> is not a C-like enum (one of its variants has a field), so its <a href="https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-field-less-enumerations" title="https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-field-less-enumerations">discriminant is implementation defined</a>. <code>repr</code> only affects "C-like" enums.</p>



<a name="192462497"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192462497" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192462497">(Mar 31 2020 at 22:42)</a>:</h4>
<p><span class="user-mention" data-user-id="118594">@ecstatic-morse</span> what do you mean by "implementation defined"?</p>



<a name="192462697"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192462697" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192462697">(Mar 31 2020 at 22:44)</a>:</h4>
<p>What the OP referred to as an implementation detail.</p>



<a name="192462784"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192462784" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192462784">(Mar 31 2020 at 22:45)</a>:</h4>
<p>So "implementation defined" typically means that the language doesn't specify what it is, but the implementation must. In this case it would be unspecified behavior, and the implementation is not free to specify it</p>



<a name="192462848"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192462848" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192462848">(Mar 31 2020 at 22:46)</a>:</h4>
<p>Sure.</p>



<a name="192490974"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192490974" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192490974">(Apr 01 2020 at 07:21)</a>:</h4>
<p><span class="user-mention" data-user-id="118594">@ecstatic-morse</span>  Maybe I'm misreading <a href="https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md" title="https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md">RFC-2195</a> and <a href="https://doc.rust-lang.org/nomicon/other-reprs.html#repru-repri" title="https://doc.rust-lang.org/nomicon/other-reprs.html#repru-repri">the nomicon</a> but I think they state a different behaviour.</p>



<a name="192492245"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492245" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492245">(Apr 01 2020 at 07:37)</a>:</h4>
<p>just to be clear, you have "uninitialized values" in the title but you are not actually dealing with truly uninitialized memory <a href="https://www.ralfj.de/blog/2019/07/14/uninit.html" title="https://www.ralfj.de/blog/2019/07/14/uninit.html">and all its madness</a>? everything is actually zero-initialized?</p>



<a name="192492277"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492277" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492277">(Apr 01 2020 at 07:37)</a>:</h4>
<p>Remember however that memory can become uninitialized again, when other uninitialized memory is copied into it or when it is inside padding</p>



<a name="192492382"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492382" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492382">(Apr 01 2020 at 07:38)</a>:</h4>
<p><span class="user-mention" data-user-id="215423">@weiznich</span> the proper stream for this question would have been <a class="stream" data-stream-id="136281" href="/#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines">#t-lang/wg-unsafe-code-guidelines</a> but this should do as well. ;)<br>
Cc <span class="user-group-mention" data-user-group-id="810">@WG-unsafe-code-guidelines</span></p>



<a name="192492462"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492462" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492462">(Apr 01 2020 at 07:39)</a>:</h4>
<p>coming back to the enums, the nomicon says</p>
<blockquote>
<p>If the enum has fields, the effect is similar to the effect of repr(C) in that there is a defined layout of the type.</p>
</blockquote>
<p>so indeed I agree that this should be unspecified behavior.</p>



<a name="192492532"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492532" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492532">(Apr 01 2020 at 07:40)</a>:</h4>
<p>likely, the reference was just never updated for <code>repr</code> on dataful enums</p>



<a name="192492621"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492621" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492621">(Apr 01 2020 at 07:41)</a>:</h4>
<p>Right, zero-initialized is a better wording here.</p>



<a name="192492812"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492812" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492812">(Apr 01 2020 at 07:43)</a>:</h4>
<p>On the other hand the <a href="https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md#guide-level-explanation" title="https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md#guide-level-explanation">corresponding section</a> in the RFC says that <code>#[repr(C)]</code> on a enum with fields in equivalent with having a tag enum without fields that is <code>#[repr(Int)]</code> and a union with the field values. That said I'm not sure how far the corresponding RFC is implemented yet.</p>



<a name="192492908"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492908" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492908">(Apr 01 2020 at 07:44)</a>:</h4>
<p>that's not what the RFC says -- the RFC says its a union where each variant starts with a tag enum without fields</p>



<a name="192492926"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492926" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492926">(Apr 01 2020 at 07:45)</a>:</h4>
<p>that is <em>different</em> from having a struct, where first we have the tag and then a union for each variant</p>



<a name="192492969"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192492969" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192492969">(Apr 01 2020 at 07:45)</a>:</h4>
<p>(IIRC the difference arises when considering alignment constraints)</p>



<a name="192493003"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192493003" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192493003">(Apr 01 2020 at 07:45)</a>:</h4>
<p><code>repr(u8)</code> would not be accepted on dataful enums if the RFC was not implemented</p>



<a name="192493103"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192493103" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192493103">(Apr 01 2020 at 07:46)</a>:</h4>
<p>but it is rather strange that the RFC does not link to a tracking issue like it usually should... hm</p>



<a name="192493110"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192493110" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192493110">(Apr 01 2020 at 07:46)</a>:</h4>
<p>so given that RFC, I agree that it is okay to transmute a "bunch of zero bytes" to <code>MyOption</code>.<br>
however, notice that <code>MyOption</code> contains padding, so if you transmute it back those padding bytes will be uninitialized.</p>



<a name="192493361"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192493361" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192493361">(Apr 01 2020 at 07:49)</a>:</h4>
<p>The corresponding <a href="https://github.com/diesel-rs/diesel/pull/2325/files#diff-625fb12522937491ff5da191068f27f2R284-R295" title="https://github.com/diesel-rs/diesel/pull/2325/files#diff-625fb12522937491ff5da191068f27f2R284-R295">code in diesel</a> does basically only check if it's <code>None</code> and if so it writes a new fully initialized value there, so I would assume it cannot ever read any uninitialised values?</p>



<a name="192556883"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192556883" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192556883">(Apr 01 2020 at 16:43)</a>:</h4>
<p>I dont know what to look at in that code, but yes -- turning the value back into the enum type and then checking for <code>None</code> should work</p>



<a name="192556897"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192556897" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192556897">(Apr 01 2020 at 16:43)</a>:</h4>
<p>what would not work is <code>memcmp</code> with a bunch of zeroes</p>



<a name="192556903"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192556903" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192556903">(Apr 01 2020 at 16:43)</a>:</h4>
<p><span class="user-mention" data-user-id="215423">@weiznich</span> ^</p>



<a name="192561010"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192561010" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> weiznich <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192561010">(Apr 01 2020 at 17:09)</a>:</h4>
<p>The important part is this piece of code:</p>
<div class="codehilite"><pre><span></span><span class="c1">// This call returns a ptr to std::mem::size_of::&lt;OptionalAggregator&lt;A&gt;&gt; zeroed bytes on the first call</span>
<span class="kd">let</span><span class="w"> </span><span class="n">aggregate_context</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ffi</span>::<span class="n">sqlite3_aggregate_context</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">size_of</span>::<span class="o">&lt;</span><span class="n">OptionalAggregator</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;&gt;</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">i32</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">aggregate_context</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">NonNull</span>::<span class="n">new</span><span class="p">(</span><span class="n">aggregate_context</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">OptionalAggregator</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">aggregator</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">aggregate_context</span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">a</span><span class="o">|</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">*</span><span class="n">a</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">// we do something else with agg below, it cannot leak from this function</span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">OptionalAggregator</span>::<span class="nb">Some</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">agg</span><span class="p">))</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">agg</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="c1">// If we get back a ptr to zeroed bytes we want to write our own struct to this place.</span>
<span class="w">    </span><span class="c1">// This will initialize the value for future calls.</span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">a_ptr</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">OptionalAggregator</span>::<span class="nb">None</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">ptr</span>::<span class="n">write_unaligned</span><span class="p">(</span><span class="n">a_ptr</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="n">OptionalAggregator</span>::<span class="nb">Some</span><span class="p">(</span><span class="n">A</span>::<span class="n">default</span><span class="p">()));</span><span class="w"></span>
<span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">OptionalAggregator</span>::<span class="nb">Some</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">agg</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a_ptr</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">agg</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">unreachable</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;We&#39;ve written the aggregator above to that location, it must be there&quot;</span><span class="p">)</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">},</span><span class="w"></span>
<span class="w">    </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">unimplemented</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;Does not matter to understand the part above&quot;</span><span class="p">),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>Otherwise thanks for taking the time to answer this <span aria-label="+1" class="emoji emoji-1f44d" role="img" title="+1">:+1:</span></p>



<a name="192567014"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192567014" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dylan MacKenzie (ecstatic-morse) <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192567014">(Apr 01 2020 at 17:52)</a>:</h4>
<p><span class="user-mention silent" data-user-id="215423">weiznich</span> <a href="#narrow/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB/near/192490974" title="#narrow/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB/near/192490974">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="118594">ecstatic-morse</span>  Maybe I'm misreading <a href="https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md" title="https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md">RFC-2195</a> and <a href="https://doc.rust-lang.org/nomicon/other-reprs.html#repru-repri" title="https://doc.rust-lang.org/nomicon/other-reprs.html#repru-repri">the nomicon</a> but I think they state a different behaviour.</p>
</blockquote>
<p>Whoops. I missed RFC 2195. Sorry. Ignore me.</p>



<a name="192780189"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192780189" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192780189">(Apr 03 2020 at 09:47)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB/near/192492532" title="#narrow/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB/near/192492532">said</a>:</p>
<blockquote>
<p>likely, the reference was just never updated for <code>repr</code> on dataful enums</p>
</blockquote>
<p>so is there a follow-up here where we should update the reference?</p>



<a name="192909624"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192909624" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192909624">(Apr 04 2020 at 14:16)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> maybe file an issue to start with <span aria-label="slight smile" class="emoji emoji-1f642" role="img" title="slight smile">:slight_smile:</span></p>



<a name="192910538"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Enum%20memory%20layout%2C%20ffi%2C%20uninitialized%20values%20and%20UB/near/192910538" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Enum.20memory.20layout.2C.20ffi.2C.20uninitialized.20values.20and.20UB.html#192910538">(Apr 04 2020 at 14:37)</a>:</h4>
<p>fair: <a href="https://github.com/rust-lang/reference/issues/786" title="https://github.com/rust-lang/reference/issues/786">https://github.com/rust-lang/reference/issues/786</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>